/**
 * Matrix Framework 租户管理服务
 * 集成ABP vNext框架的租户管理功能
 */

import apiClient, { type AbpResponse, type AbpQueryResult } from '@/utils/api'
import MockService, { useMockService } from './mock.service'
import type {
  Tenant,
  CreateTenantRequest,
  UpdateTenantRequest,
  TenantQueryParams,
  TenantQueryResult,
  TenantStatistics,
  KeycloakRealmInfo,
  KeycloakClientInfo,
  TenantFeature,
  TenantSetting,
  TenantOperationLog,
  TenantAdmin,
  TenantUserStatistics,
  ImportTenantRequest,
  ExportTenantRequest,
  BulkTenantOperationRequest,
  ValidateConnectionStringRequest,
  ValidateConnectionStringResult,
  TenantHealthCheckResult,
  CreateTenantBackupRequest,
  RestoreTenantBackupRequest,
  TenantBackup,
  TenantActivityLog
} from '@/types/tenant'
import type { AbpResponse } from '@/types/abp'
import abpService from './abp.service'

class TenantService {
  private static instance: TenantService
  private readonly apiBasePath = '/api/tenant-management/tenants'

  private constructor() {}

  /**
   * 获取单例实例
   */
  static getInstance(): TenantService {
    if (!TenantService.instance) {
      TenantService.instance = new TenantService()
    }
    return TenantService.instance
  }

  // ==================== 租户CRUD操作 ====================

  /**
   * 获取租户列表
   */
  async getTenants(params: TenantQueryParams = {}): Promise<TenantQueryResult> {
    try {
      // 检查权限
      if (!abpService.hasPermission('TenantManagement.Tenants')) {
        throw new Error('没有租户管理权限')
      }

      // 如果启用Mock服务，使用Mock数据
      if (useMockService) {
        return await MockService.getTenantList(params)
      }

      // 使用真实API
      const response = await apiClient.get<TenantQueryResult>(
        this.apiBasePath,
        { params }
      )

      return response
    } catch (error) {
      console.error('获取租户列表失败:', error)
      throw error
    }
  }

  /**
   * 根据ID获取租户详情
   */
  async getTenantById(id: string): Promise<Tenant> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants')) {
        throw new Error('没有租户管理权限')
      }

      const response = await axios.get<AbpResponse<Tenant>>(
        `${this.apiBasePath}/${id}`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户详情失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 创建租户
   */
  async createTenant(request: CreateTenantRequest): Promise<Tenant> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Create')) {
        throw new Error('没有创建租户权限')
      }

      if (useMockService) {
        return await MockService.createTenant(request)
      }

      const response = await apiClient.post<Tenant>(
        this.apiBasePath,
        request
      )

      abpService.log('Information', `租户 "${request.displayName}" 创建成功`, {
        tenantName: request.name,
        operation: 'CreateTenant'
      })

      return response
    } catch (error) {
      console.error('创建租户失败:', error)
      throw error
    }
  }

  /**
   * 更新租户
   */
  async updateTenant(id: string, request: UpdateTenantRequest): Promise<Tenant> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Update')) {
        throw new Error('没有更新租户权限')
      }

      const response = await axios.put<AbpResponse<Tenant>>(
        `${this.apiBasePath}/${id}`,
        request
      )

      abpService.log('Information', `租户 "${request.displayName}" 更新成功`, {
        tenantId: id,
        operation: 'UpdateTenant'
      })

      return response.data.result
    } catch (error) {
      console.error(`更新租户失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 删除租户
   */
  async deleteTenant(id: string): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Delete')) {
        throw new Error('没有删除租户权限')
      }

      await axios.delete(`${this.apiBasePath}/${id}`)

      abpService.log('Warning', `租户删除成功`, {
        tenantId: id,
        operation: 'DeleteTenant'
      })
    } catch (error) {
      console.error(`删除租户失败 [${id}]:`, error)
      throw error
    }
  }

  // ==================== 租户管理操作 ====================

  /**
   * 激活租户
   */
  async activateTenant(id: string): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Update')) {
        throw new Error('没有更新租户权限')
      }

      await axios.post(`${this.apiBasePath}/${id}/activate`)

      abpService.log('Information', `租户激活成功`, {
        tenantId: id,
        operation: 'ActivateTenant'
      })
    } catch (error) {
      console.error(`激活租户失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 停用租户
   */
  async deactivateTenant(id: string): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Update')) {
        throw new Error('没有更新租户权限')
      }

      await axios.post(`${this.apiBasePath}/${id}/deactivate`)

      abpService.log('Warning', `租户停用成功`, {
        tenantId: id,
        operation: 'DeactivateTenant'
      })
    } catch (error) {
      console.error(`停用租户失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 批量操作租户
   */
  async bulkOperation(request: BulkTenantOperationRequest): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Update')) {
        throw new Error('没有批量操作租户权限')
      }

      await axios.post(`${this.apiBasePath}/bulk-operation`, request)

      abpService.log('Information', `租户批量操作成功`, {
        operation: request.operation,
        tenantCount: request.tenantIds.length
      })
    } catch (error) {
      console.error('批量操作租户失败:', error)
      throw error
    }
  }

  // ==================== Keycloak集成 ====================

  /**
   * 获取Keycloak Realm信息
   */
  async getKeycloakRealm(tenantId: string): Promise<KeycloakRealmInfo> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Keycloak')) {
        throw new Error('没有Keycloak管理权限')
      }

      const response = await axios.get<AbpResponse<KeycloakRealmInfo>>(
        `${this.apiBasePath}/${tenantId}/keycloak-realm`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取Keycloak Realm失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 创建Keycloak Realm
   */
  async createKeycloakRealm(tenantId: string, realmName: string): Promise<KeycloakRealmInfo> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Keycloak')) {
        throw new Error('没有Keycloak管理权限')
      }

      const response = await axios.post<AbpResponse<KeycloakRealmInfo>>(
        `${this.apiBasePath}/${tenantId}/keycloak-realm`,
        { realmName }
      )

      abpService.log('Information', `Keycloak Realm创建成功`, {
        tenantId,
        realmName,
        operation: 'CreateKeycloakRealm'
      })

      return response.data.result
    } catch (error) {
      console.error(`创建Keycloak Realm失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 更新Keycloak Realm
   */
  async updateKeycloakRealm(tenantId: string, realmInfo: Partial<KeycloakRealmInfo>): Promise<KeycloakRealmInfo> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Keycloak')) {
        throw new Error('没有Keycloak管理权限')
      }

      const response = await axios.put<AbpResponse<KeycloakRealmInfo>>(
        `${this.apiBasePath}/${tenantId}/keycloak-realm`,
        realmInfo
      )

      return response.data.result
    } catch (error) {
      console.error(`更新Keycloak Realm失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 获取Keycloak客户端信息
   */
  async getKeycloakClient(tenantId: string): Promise<KeycloakClientInfo> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Keycloak')) {
        throw new Error('没有Keycloak管理权限')
      }

      const response = await axios.get<AbpResponse<KeycloakClientInfo>>(
        `${this.apiBasePath}/${tenantId}/keycloak-client`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取Keycloak客户端失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 同步Keycloak用户到Matrix Framework
   */
  async syncKeycloakUsers(tenantId: string): Promise<{ syncedCount: number; failedCount: number }> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Sync')) {
        throw new Error('没有用户同步权限')
      }

      const response = await axios.post<AbpResponse<{ syncedCount: number; failedCount: number }>>(
        `${this.apiBasePath}/${tenantId}/sync-keycloak-users`
      )

      abpService.log('Information', `Keycloak用户同步完成`, {
        tenantId,
        operation: 'SyncKeycloakUsers',
        result: response.data.result
      })

      return response.data.result
    } catch (error) {
      console.error(`同步Keycloak用户失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户功能管理 ====================

  /**
   * 获取租户功能列表
   */
  async getTenantFeatures(tenantId: string): Promise<TenantFeature[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.Features')) {
        throw new Error('没有功能管理权限')
      }

      const response = await axios.get<AbpResponse<TenantFeature[]>>(
        `${this.apiBasePath}/${tenantId}/features`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户功能失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 更新租户功能
   */
  async updateTenantFeatures(tenantId: string, features: Record<string, any>): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Features.Update')) {
        throw new Error('没有更新功能权限')
      }

      await axios.put(`${this.apiBasePath}/${tenantId}/features`, { features })

      abpService.log('Information', `租户功能更新成功`, {
        tenantId,
        operation: 'UpdateTenantFeatures'
      })
    } catch (error) {
      console.error(`更新租户功能失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 重置租户功能到默认值
   */
  async resetTenantFeatures(tenantId: string): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Features.Update')) {
        throw new Error('没有重置功能权限')
      }

      await axios.post(`${this.apiBasePath}/${tenantId}/features/reset`)

      abpService.log('Information', `租户功能重置成功`, {
        tenantId,
        operation: 'ResetTenantFeatures'
      })
    } catch (error) {
      console.error(`重置租户功能失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户设置管理 ====================

  /**
   * 获取租户设置列表
   */
  async getTenantSettings(tenantId: string): Promise<TenantSetting[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.Settings')) {
        throw new Error('没有设置管理权限')
      }

      const response = await axios.get<AbpResponse<TenantSetting[]>>(
        `${this.apiBasePath}/${tenantId}/settings`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户设置失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 更新租户设置
   */
  async updateTenantSettings(tenantId: string, settings: Record<string, string>): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Settings.Update')) {
        throw new Error('没有更新设置权限')
      }

      await axios.put(`${this.apiBasePath}/${tenantId}/settings`, { settings })

      abpService.log('Information', `租户设置更新成功`, {
        tenantId,
        operation: 'UpdateTenantSettings'
      })
    } catch (error) {
      console.error(`更新租户设置失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户用户管理 ====================

  /**
   * 获取租户管理员
   */
  async getTenantAdmins(tenantId: string): Promise<TenantAdmin[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.TenantUsers')) {
        throw new Error('没有租户用户管理权限')
      }

      const response = await axios.get<AbpResponse<TenantAdmin[]>>(
        `${this.apiBasePath}/${tenantId}/admins`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户管理员失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 获取租户用户统计
   */
  async getTenantUserStatistics(tenantId: string): Promise<TenantUserStatistics> {
    try {
      if (!abpService.hasPermission('TenantManagement.TenantUsers')) {
        throw new Error('没有租户用户管理权限')
      }

      const response = await axios.get<AbpResponse<TenantUserStatistics>>(
        `${this.apiBasePath}/${tenantId}/user-statistics`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户用户统计失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户统计和分析 ====================

  /**
   * 获取租户统计信息
   */
  async getTenantStatistics(): Promise<TenantStatistics> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants')) {
        throw new Error('没有租户管理权限')
      }

      const response = await axios.get<AbpResponse<TenantStatistics>>(
        `${this.apiBasePath}/statistics`
      )

      return response.data.result
    } catch (error) {
      console.error('获取租户统计失败:', error)
      throw error
    }
  }

  /**
   * 获取租户操作日志
   */
  async getTenantOperationLogs(tenantId?: string): Promise<TenantOperationLog[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.Logs')) {
        throw new Error('没有日志查看权限')
      }

      const url = tenantId
        ? `${this.apiBasePath}/${tenantId}/operation-logs`
        : `${this.apiBasePath}/operation-logs`

      const response = await axios.get<AbpResponse<TenantOperationLog[]>>(url)

      return response.data.result
    } catch (error) {
      console.error('获取租户操作日志失败:', error)
      throw error
    }
  }

  /**
   * 获取租户活动日志
   */
  async getTenantActivityLogs(tenantId: string): Promise<TenantActivityLog[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.Logs')) {
        throw new Error('没有日志查看权限')
      }

      const response = await axios.get<AbpResponse<TenantActivityLog[]>>(
        `${this.apiBasePath}/${tenantId}/activity-logs`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户活动日志失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户健康检查 ====================

  /**
   * 执行租户健康检查
   */
  async performTenantHealthCheck(tenantId: string): Promise<TenantHealthCheckResult> {
    try {
      if (!abpService.hasPermission('TenantManagement.HealthCheck')) {
        throw new Error('没有健康检查权限')
      }

      const response = await axios.post<AbpResponse<TenantHealthCheckResult>>(
        `${this.apiBasePath}/${tenantId}/health-check`
      )

      return response.data.result
    } catch (error) {
      console.error(`租户健康检查失败 [${tenantId}]:`, error)
      throw error
    }
  }

  /**
   * 获取租户健康检查结果
   */
  async getTenantHealthCheckResult(tenantId: string): Promise<TenantHealthCheckResult> {
    try {
      if (!abpService.hasPermission('TenantManagement.HealthCheck')) {
        throw new Error('没有健康检查权限')
      }

      const response = await axios.get<AbpResponse<TenantHealthCheckResult>>(
        `${this.apiBasePath}/${tenantId}/health-check`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取租户健康检查结果失败 [${tenantId}]:`, error)
      throw error
    }
  }

  // ==================== 租户备份和恢复 ====================

  /**
   * 创建租户备份
   */
  async createTenantBackup(request: CreateTenantBackupRequest): Promise<TenantBackup> {
    try {
      if (!abpService.hasPermission('TenantManagement.Backup.Create')) {
        throw new Error('没有创建备份权限')
      }

      const response = await axios.post<AbpResponse<TenantBackup>>(
        `${this.apiBasePath}/backups`,
        request
      )

      abpService.log('Information', `租户备份创建成功`, {
        tenantId: request.tenantId,
        backupType: request.type,
        operation: 'CreateTenantBackup'
      })

      return response.data.result
    } catch (error) {
      console.error('创建租户备份失败:', error)
      throw error
    }
  }

  /**
   * 获取租户备份列表
   */
  async getTenantBackups(tenantId?: string): Promise<TenantBackup[]> {
    try {
      if (!abpService.hasPermission('TenantManagement.Backup.List')) {
        throw new Error('没有查看备份权限')
      }

      const url = tenantId
        ? `${this.apiBasePath}/${tenantId}/backups`
        : `${this.apiBasePath}/backups`

      const response = await axios.get<AbpResponse<TenantBackup[]>>(url)

      return response.data.result
    } catch (error) {
      console.error('获取租户备份列表失败:', error)
      throw error
    }
  }

  /**
   * 恢复租户备份
   */
  async restoreTenantBackup(request: RestoreTenantBackupRequest): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Backup.Restore')) {
        throw new Error('没有恢复备份权限')
      }

      await axios.post(`${this.apiBasePath}/backups/restore`, request)

      abpService.log('Information', `租户备份恢复成功`, {
        backupId: request.backupId,
        operation: 'RestoreTenantBackup'
      })
    } catch (error) {
      console.error('恢复租户备份失败:', error)
      throw error
    }
  }

  /**
   * 删除租户备份
   */
  async deleteTenantBackup(backupId: string): Promise<void> {
    try {
      if (!abpService.hasPermission('TenantManagement.Backup.Delete')) {
        throw new Error('没有删除备份权限')
      }

      await axios.delete(`${this.apiBasePath}/backups/${backupId}`)

      abpService.log('Information', `租户备份删除成功`, {
        backupId,
        operation: 'DeleteTenantBackup'
      })
    } catch (error) {
      console.error(`删除租户备份失败 [${backupId}]:`, error)
      throw error
    }
  }

  // ==================== 导入导出功能 ====================

  /**
   * 导入租户
   */
  async importTenants(request: ImportTenantRequest): Promise<{ successCount: number; failureCount: number }> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Import')) {
        throw new Error('没有导入租户权限')
      }

      const formData = new FormData()
      formData.append('file', request.file)
      formData.append('overwriteExisting', request.overwriteExisting.toString())
      formData.append('sendWelcomeEmail', request.sendWelcomeEmail.toString())

      const response = await axios.post<AbpResponse<{ successCount: number; failureCount: number }>>(
        `${this.apiBasePath}/import`,
        formData,
        {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }
      )

      abpService.log('Information', `租户导入完成`, {
        fileName: request.file.name,
        result: response.data.result,
        operation: 'ImportTenants'
      })

      return response.data.result
    } catch (error) {
      console.error('导入租户失败:', error)
      throw error
    }
  }

  /**
   * 导出租户
   */
  async exportTenants(request: ExportTenantRequest): Promise<Blob> {
    try {
      if (!abpService.hasPermission('TenantManagement.Tenants.Export')) {
        throw new Error('没有导出租户权限')
      }

      const response = await axios.post(
        `${this.apiBasePath}/export`,
        request,
        {
          responseType: 'blob'
        }
      )

      abpService.log('Information', `租户导出完成`, {
        format: request.format,
        tenantCount: request.tenantIds.length,
        operation: 'ExportTenants'
      })

      return response.data
    } catch (error) {
      console.error('导出租户失败:', error)
      throw error
    }
  }

  // ==================== 连接字符串管理 ====================

  /**
   * 验证连接字符串
   */
  async validateConnectionString(request: ValidateConnectionStringRequest): Promise<ValidateConnectionStringResult> {
    try {
      if (!abpService.hasPermission('TenantManagement.ConnectionStrings.Validate')) {
        throw new Error('没有验证连接字符串权限')
      }

      const response = await axios.post<AbpResponse<ValidateConnectionStringResult>>(
        `${this.apiBasePath}/validate-connection-string`,
        request
      )

      return response.data.result
    } catch (error) {
      console.error('验证连接字符串失败:', error)
      throw error
    }
  }

  /**
   * 测试租户连接
   */
  async testTenantConnection(tenantId: string): Promise<{ isHealthy: boolean; responseTime: number }> {
    try {
      if (!abpService.hasPermission('TenantManagement.ConnectionStrings.Test')) {
        throw new Error('没有测试连接权限')
      }

      const response = await axios.post<AbpResponse<{ isHealthy: boolean; responseTime: number }>>(
        `${this.apiBasePath}/${tenantId}/test-connection`
      )

      return response.data.result
    } catch (error) {
      console.error(`测试租户连接失败 [${tenantId}]:`, error)
      throw error
    }
  }
}

// 创建单例实例
const tenantService = TenantService.getInstance()

export default tenantService
export { TenantService }
export type {
  Tenant,
  CreateTenantRequest,
  UpdateTenantRequest,
  TenantQueryParams,
  TenantQueryResult,
  TenantStatistics,
  KeycloakRealmInfo,
  KeycloakClientInfo,
  TenantFeature,
  TenantSetting,
  TenantOperationLog,
  TenantAdmin,
  TenantUserStatistics
}